-
Notifications
You must be signed in to change notification settings - Fork 9.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
core(fr): handle 0 throughput in timespan #13323
Conversation
I'm on my phone so can't check for myself, sorry, but what's the difference between timespan and navigation for this? I thought we estimated from the download rate in cases like this... Is it we don't have that info in a timespan? |
We estimate from the throughput in timespan, which is calculated using lighthouse/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js Lines 207 to 212 in 5d8ea1a
|
for myself: the difference is that estimating via throughput isn't done for navigation, that uses the full graph simulation: lighthouse/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js Lines 227 to 234 in 5d8ea1a
If instead we did call
sorry, the missing object in It looks like we only do that for lighthouse/lighthouse-core/computed/load-simulator.js Lines 40 to 43 in 5d8ea1a
which is estimated over in We know we have network records due to this check: lighthouse/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js Lines 120 to 128 in 68ba77a
what if we altered |
kind of ugly version of what I mean, ideally we can do this nicer (but the file might need a refactor for the FR world it lives in now that we don't want to take on at this point): diff --git a/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js b/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js
index 4c6e17abe..bae49d2ba 100644
--- a/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js
+++ b/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js
@@ -12,6 +12,7 @@ const i18n = require('../../lib/i18n/i18n.js');
const NetworkRecords = require('../../computed/network-records.js');
const LoadSimulator = require('../../computed/load-simulator.js');
const PageDependencyGraph = require('../../computed/page-dependency-graph.js');
+const NetworkAnalysis = require('../../computed/network-analysis.js');
const str_ = i18n.createMessageInstanceIdFn(__filename, {});
@@ -127,16 +128,17 @@ class UnusedBytes extends Audit {
};
}
- const [result, graph, simulator] = await Promise.all([
+ const [result, graph, simulator, networkAnalysis] = await Promise.all([
this.audit_(artifacts, networkRecords, context),
// Page dependency graph is only used in navigation mode.
gatherContext.gatherMode === 'navigation' ?
PageDependencyGraph.request({trace, devtoolsLog}, context) :
null,
LoadSimulator.request(simulatorOptions, context),
+ NetworkAnalysis.request(devtoolsLog, context),
]);
- return this.createAuditProduct(result, graph, simulator, gatherContext);
+ return this.createAuditProduct(result, graph, simulator, gatherContext, networkAnalysis);
}
/**
@@ -203,9 +205,13 @@ class UnusedBytes extends Audit {
/**
* @param {number} wastedBytes
* @param {Simulator} simulator
+ * @param {LH.Artifacts.NetworkAnalysis} networkAnalysis
*/
- static computeWastedMsWithThroughput(wastedBytes, simulator) {
- const bitsPerSecond = simulator.getOptions().throughput;
+ static computeWastedMsWithThroughput(wastedBytes, simulator, networkAnalysis) {
+ let bitsPerSecond = simulator.getOptions().throughput;
+ if (bitsPerSecond === 0) {
+ bitsPerSecond = networkAnalysis.throughput;
+ }
const wastedBits = wastedBytes * 8;
const wastedMs = wastedBits / bitsPerSecond * 1000;
return wastedMs;
@@ -216,9 +222,10 @@ class UnusedBytes extends Audit {
* @param {Node|null} graph
* @param {Simulator} simulator
* @param {LH.Artifacts['GatherContext']} gatherContext
+ * @param {LH.Artifacts.NetworkAnalysis} networkAnalysis
* @return {LH.Audit.Product}
*/
- static createAuditProduct(result, graph, simulator, gatherContext) {
+ static createAuditProduct(result, graph, simulator, gatherContext, networkAnalysis) {
const results = result.items.sort((itemA, itemB) => itemB.wastedBytes - itemA.wastedBytes);
const wastedBytes = results.reduce((sum, item) => sum + item.wastedBytes, 0);
@@ -230,7 +237,7 @@ class UnusedBytes extends Audit {
providedWastedBytesByUrl: result.wastedBytesByUrl,
});
} else {
- wastedMs = this.computeWastedMsWithThroughput(wastedBytes, simulator);
+ wastedMs = this.computeWastedMsWithThroughput(wastedBytes, simulator, networkAnalysis);
}
let displayValue = result.displayValue || ''; extra computation cost is minimal because simulator creation also runs
this should cover us, but |
The simulator doesn't have any NaN issues with navigations, but does it make sense to have simulator options |
} | ||
|
||
// 0 should be interpreted as "unset" for these values. | ||
// Fallback to environment values in this case. | ||
if (options.rtt === 0) options.rtt = networkAnalysis.rtt; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assumed this is true for rtt
but it shouldn't be necessary to fix the issue at hand.
Well, now you've made me come all the way around and I think your initial proposal is the right one, haha. Most of this you already said above but to try to summarize for posterity: The reason the simulator only uses the estimated throughput value for When throttling is But since the timespan case is just doing a super naive calculation ( So I think:
|
One notable difference is... in lantern, throughput and rtt are used "correctly", in that our simulated environment ensures the throughput affects network transmission to the best of our abilities. However in our devtools throttling, both the rtt and throttling numbers are additive. We'd just adding extra latency and constraining throughput beyond what's happening in real life. (put another way... if you wanted to know what rtt of 2ms and throughput of 1gb looks like... lantern would be ~accurate, but w/ devtools your results would be basically indicative of your machine's actual network conditions) So... given that we have additive throttling in devtools.. it makes me think our BE |
three possibilities
|
@adamraine if you wanna land this with option 1 (as listed above), i'm only comfortable doing that as a super quick solution to avoid NaN. options 2 and 3 are the only options that provide "correct" results, so i'd expect we'd followup in the shortterm with one of those. |
Lets do option 1 for v9, that's what's implemented now |
…lighthouse into fr-timespan-throughput-fix
Closes #13321
This appears to be the correct solution given how we calculate savings in timespan mode, but it also means that
wastedMs
will be 0 for every BE audit in timespan mode using the desktop config.